﻿using JT808.Protocol.Extensions.JTActiveSafety.Metadata;
using JTActiveSafety.Gateway.Abstractions;
using JTActiveSafety.Gateway.Services;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Timers;

namespace JTActiveSafety.Gateway.Sessions
{
    /// <summary>
    /// 
    /// </summary>
    public class JTActiveSafetySessionManager
    {
        private readonly ILogger _logger;
        private ConcurrentDictionary<string, JTActiveSafetySession> _sessions = new ConcurrentDictionary<string, JTActiveSafetySession>(StringComparer.OrdinalIgnoreCase);
        private Timer timerTimeout = new Timer();

        public JTActiveSafetySessionManager(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger("JTActiveSafety.Hosting.Server");
            timerTimeout.Elapsed += new ElapsedEventHandler(OnTimeout);
        }
        private void OnTimeout(object sender, ElapsedEventArgs e)
        {
            var timeout = DateTime.Now.AddSeconds(0 - SessionTimeout);
            foreach (var item in _sessions.Values.Where(c => c.LastActiveTime < timeout).ToList())
            {
                _sessions.TryRemove(item.SessionId, out _);
            }
        }
        /// <summary>
        /// 会话超时时间,默认10分钟（单位：s）
        /// </summary>
        public int SessionTimeout { get; set; } = 60 * 10;

        private int _checkSessionTimeout = 60;
        /// <summary>
        /// 检查超时频率，默认1分钟检查一次（单位：s）
        /// </summary>
        public int CheckSessionTimeout
        {
            get
            {
                return _checkSessionTimeout;
            }
            set
            {
                if (value > 0)
                {
                    timerTimeout.Interval = value;
                }
                _checkSessionTimeout = value;
            }
        }

        public int TotalSessionCount
        {
            get
            {
                return _sessions.Count;
            }
        }

        public int TcpSessionCount
        {
            get
            {
                return _sessions.Where(w => w.Value.TransportProtocolType == JTActiveSafetyTransportProtocolType.tcp).Count();
            }
        }

        public int UdpSessionCount
        {
            get
            {
                return _sessions.Where(w => w.Value.TransportProtocolType == JTActiveSafetyTransportProtocolType.udp).Count();
            }
        }

        public List<JTActiveSafetyTcpSession> TcpSessions
        {
            get { return _sessions.Where(w => w.Value.TransportProtocolType == JTActiveSafetyTransportProtocolType.tcp).Select(s => (JTActiveSafetyTcpSession)s.Value).ToList(); }
        }

        public List<JTActiveSafetyUdpSession> UdpSessions
        {
            get
            {
                return _sessions.Where(w => w.Value.TransportProtocolType == JTActiveSafetyTransportProtocolType.udp).Select(s => (JTActiveSafetyUdpSession)s.Value).ToList();
            }
        }
        public List<JTActiveSafetySession> Sessions { get { return _sessions.Values.ToList(); } }

        public void AddOrUpdate(JTActiveSafetySession session)
        {
            _sessions.AddOrUpdate(session.SessionId, session, (k, v) =>
            {
                v.LastActiveTime = DateTime.Now;
                return v;
            });
        }

        public void Remove(string sessionId)
        {
            if (_sessions.TryRemove(sessionId, out var _))
            {

            }
        }


    }
}
